{
 "cells": [
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "基于dataset\\training_set数据，根据提供的结构，建立CNN模型，识别图片中的猫/狗，计算预测准确率：\n",
    "1.识别图片中的猫/狗、计算dataset\\test_set测试数据预测准确率\n",
    "2.从网站下载猫/狗图片，对其进行预测"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "@Author  : Flare Zhao\n",
    "@Email: 454209979@qq.com\n",
    "@QQ讨论群：530533630  申请加群的验证信息为订单号（粘贴号码数字即可）\n",
    "@如果觉得课程不错的话，欢迎推荐朋友学习，发送朋友截图（含报名日期）和订单号至老师邮箱，返还100元学费"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-06-20T12:28:53.577197400Z",
     "start_time": "2023-06-20T12:28:53.197681400Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Found 8000 images belonging to 2 classes.\n"
     ]
    }
   ],
   "source": [
    "#load the data\n",
    "from keras.preprocessing.image import ImageDataGenerator\n",
    "train_datagen = ImageDataGenerator(rescale=1./255)\n",
    "\n",
    "training_set = train_datagen.flow_from_directory('./dataset/training_set',target_size=(50,50),batch_size=32,class_mode='binary')\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-06-20T12:28:53.641593400Z",
     "start_time": "2023-06-20T12:28:53.581747900Z"
    }
   },
   "outputs": [],
   "source": [
    "#set up the cnn model\n",
    "from keras.models import Sequential\n",
    "from keras.layers import Conv2D, MaxPool2D, Flatten, Dense\n",
    "\n",
    "model = Sequential()\n",
    "#卷积层\n",
    "model.add(Conv2D(32,(3,3),input_shape=(50,50,3),activation='relu'))\n",
    "#池化层\n",
    "model.add(MaxPool2D(pool_size=(2,2)))\n",
    "#卷积层\n",
    "model.add(Conv2D(32,(3,3),activation='relu'))\n",
    "#池化层\n",
    "model.add(MaxPool2D(pool_size=(2,2)))\n",
    "#flattening layer\n",
    "model.add(Flatten())\n",
    "#FC layer\n",
    "model.add(Dense(units=128,activation='relu'))\n",
    "model.add(Dense(units=1,activation='sigmoid'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-06-20T12:28:53.653635600Z",
     "start_time": "2023-06-20T12:28:53.641593400Z"
    }
   },
   "outputs": [],
   "source": [
    "#configure the model\n",
    "model.compile(optimizer='adam',loss='binary_crossentropy',metrics=['accuracy'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-06-20T12:28:53.700091100Z",
     "start_time": "2023-06-20T12:28:53.654640100Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Model: \"sequential_1\"\n",
      "_________________________________________________________________\n",
      "Layer (type)                 Output Shape              Param #   \n",
      "=================================================================\n",
      "conv2d_2 (Conv2D)            (None, 48, 48, 32)        896       \n",
      "_________________________________________________________________\n",
      "max_pooling2d_2 (MaxPooling2 (None, 24, 24, 32)        0         \n",
      "_________________________________________________________________\n",
      "conv2d_3 (Conv2D)            (None, 22, 22, 32)        9248      \n",
      "_________________________________________________________________\n",
      "max_pooling2d_3 (MaxPooling2 (None, 11, 11, 32)        0         \n",
      "_________________________________________________________________\n",
      "flatten_1 (Flatten)          (None, 3872)              0         \n",
      "_________________________________________________________________\n",
      "dense_2 (Dense)              (None, 128)               495744    \n",
      "_________________________________________________________________\n",
      "dense_3 (Dense)              (None, 1)                 129       \n",
      "=================================================================\n",
      "Total params: 506,017\n",
      "Trainable params: 506,017\n",
      "Non-trainable params: 0\n",
      "_________________________________________________________________\n"
     ]
    }
   ],
   "source": [
    "model.summary()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![cnn_structure](structure.jpg)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-06-20T12:29:46.746268Z",
     "start_time": "2023-06-20T12:28:53.670270900Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 1/5\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\薛国鹏\\AppData\\Local\\Programs\\Python\\Python36\\lib\\site-packages\\keras\\engine\\training.py:1972: UserWarning: `Model.fit_generator` is deprecated and will be removed in a future version. Please use `Model.fit`, which supports generators.\n",
      "  warnings.warn('`Model.fit_generator` is deprecated and '\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "250/250 [==============================] - 11s 43ms/step - loss: 0.6794 - accuracy: 0.5620\n",
      "Epoch 2/5\n",
      "250/250 [==============================] - 10s 42ms/step - loss: 0.5839 - accuracy: 0.6949\n",
      "Epoch 3/5\n",
      "250/250 [==============================] - 10s 42ms/step - loss: 0.5188 - accuracy: 0.7405\n",
      "Epoch 4/5\n",
      "250/250 [==============================] - 11s 42ms/step - loss: 0.4672 - accuracy: 0.7825\n",
      "Epoch 5/5\n",
      "250/250 [==============================] - 10s 41ms/step - loss: 0.4247 - accuracy: 0.8043\n"
     ]
    },
    {
     "data": {
      "text/plain": "<keras.callbacks.History at 0x1ebb9f713c8>"
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#train the model\n",
    "model.fit_generator(training_set,epochs=5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-06-20T12:29:53.949807800Z",
     "start_time": "2023-06-20T12:29:46.746268Z"
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\薛国鹏\\AppData\\Local\\Programs\\Python\\Python36\\lib\\site-packages\\keras\\engine\\training.py:2006: UserWarning: `Model.evaluate_generator` is deprecated and will be removed in a future version. Please use `Model.evaluate`, which supports generators.\n",
      "  warnings.warn('`Model.evaluate_generator` is deprecated and '\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0.38809138536453247, 0.8343750238418579]\n"
     ]
    }
   ],
   "source": [
    "#accuracy on the training data\n",
    "accuracy_train = model.evaluate_generator(training_set)\n",
    "print(accuracy_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-06-20T12:29:56.529590500Z",
     "start_time": "2023-06-20T12:29:53.951805800Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Found 2000 images belonging to 2 classes.\n",
      "[0.4819526672363281, 0.7789999842643738]\n"
     ]
    }
   ],
   "source": [
    "#accuracy on the test data\n",
    "test_set = train_datagen.flow_from_directory('./dataset/test_set',target_size=(50,50),batch_size=32,class_mode='binary')\n",
    "\n",
    "accuracy_test = model.evaluate_generator(test_set)\n",
    "print(accuracy_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-06-20T12:29:56.578043Z",
     "start_time": "2023-06-20T12:29:56.530967300Z"
    }
   },
   "outputs": [
    {
     "ename": "AttributeError",
     "evalue": "'Sequential' object has no attribute 'predict_classes'",
     "output_type": "error",
     "traceback": [
      "\u001B[1;31m---------------------------------------------------------------------------\u001B[0m",
      "\u001B[1;31mAttributeError\u001B[0m                            Traceback (most recent call last)",
      "\u001B[1;32m<ipython-input-13-4190f925fdd6>\u001B[0m in \u001B[0;36m<module>\u001B[1;34m\u001B[0m\n\u001B[0;32m      6\u001B[0m \u001B[0mpic_dog\u001B[0m \u001B[1;33m=\u001B[0m \u001B[0mpic_dog\u001B[0m\u001B[1;33m/\u001B[0m\u001B[1;36m255\u001B[0m\u001B[1;33m\u001B[0m\u001B[0m\n\u001B[0;32m      7\u001B[0m \u001B[0mpic_dog\u001B[0m \u001B[1;33m=\u001B[0m \u001B[0mpic_dog\u001B[0m\u001B[1;33m.\u001B[0m\u001B[0mreshape\u001B[0m\u001B[1;33m(\u001B[0m\u001B[1;36m1\u001B[0m\u001B[1;33m,\u001B[0m\u001B[1;36m50\u001B[0m\u001B[1;33m,\u001B[0m\u001B[1;36m50\u001B[0m\u001B[1;33m,\u001B[0m\u001B[1;36m3\u001B[0m\u001B[1;33m)\u001B[0m\u001B[1;33m\u001B[0m\u001B[0m\n\u001B[1;32m----> 8\u001B[1;33m \u001B[0mresult\u001B[0m \u001B[1;33m=\u001B[0m \u001B[0mmodel\u001B[0m\u001B[1;33m.\u001B[0m\u001B[0mpredict_classes\u001B[0m\u001B[1;33m(\u001B[0m\u001B[0mpic_dog\u001B[0m\u001B[1;33m)\u001B[0m\u001B[1;33m\u001B[0m\u001B[0m\n\u001B[0m\u001B[0;32m      9\u001B[0m \u001B[0mprint\u001B[0m\u001B[1;33m(\u001B[0m\u001B[0mresult\u001B[0m\u001B[1;33m)\u001B[0m\u001B[1;33m\u001B[0m\u001B[0m\n",
      "\u001B[1;31mAttributeError\u001B[0m: 'Sequential' object has no attribute 'predict_classes'"
     ]
    }
   ],
   "source": [
    "#load single image\n",
    "from keras.preprocessing.image import load_img, img_to_array\n",
    "pic_dog = 'dog.jpg'\n",
    "pic_dog = load_img(pic_dog,target_size=(50,50))\n",
    "pic_dog = img_to_array(pic_dog)\n",
    "pic_dog = pic_dog/255\n",
    "pic_dog = pic_dog.reshape(1,50,50,3)\n",
    "result = model.predict_classes(pic_dog)\n",
    "print(result)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "start_time": "2023-06-20T12:29:56.559506800Z"
    }
   },
   "outputs": [],
   "source": [
    "pic_cat = 'cat1.jpg'\n",
    "pic_cat = load_img(pic_cat,target_size=(50,50))\n",
    "pic_cat = img_to_array(pic_cat)\n",
    "pic_cat = pic_cat/255\n",
    "pic_cat = pic_cat.reshape(1,50,50,3)\n",
    "result = model.predict_classes(pic_cat)\n",
    "print(result)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "start_time": "2023-06-20T12:29:56.561510100Z"
    }
   },
   "outputs": [],
   "source": [
    "training_set.class_indices"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "start_time": "2023-06-20T12:29:56.562511100Z"
    }
   },
   "outputs": [],
   "source": [
    "# make prediction on multiple images\n",
    "import matplotlib as mlp\n",
    "font2 = {'family' : 'SimHei',\n",
    "'weight' : 'normal',\n",
    "'size'   : 20,\n",
    "}\n",
    "mlp.rcParams['font.family'] = 'SimHei'\n",
    "mlp.rcParams['axes.unicode_minus'] = False\n",
    "from matplotlib import pyplot as plt\n",
    "from matplotlib.image import imread\n",
    "from keras.preprocessing.image import load_img\n",
    "from keras.preprocessing.image import img_to_array\n",
    "from keras.models import load_model\n",
    "a = [i for i in range(1,10)]\n",
    "fig = plt.figure(figsize=(10,10))\n",
    "for i in a:\n",
    "    img_name = str(i)+'.jpg'\n",
    "    img_ori = load_img(img_name, target_size=(50, 50))\n",
    "    img = img_to_array(img_ori)\n",
    "    img = img.astype('float32')/255\n",
    "    img = img.reshape(1,50,50,3)\n",
    "    result = model.predict_classes(img)\n",
    "    img_ori = load_img(img_name, target_size=(250, 250))\n",
    "    plt.subplot(3,3,i)\n",
    "    plt.imshow(img_ori)\n",
    "    plt.title('预测为：狗狗' if result[0][0] == 1 else '预测为：猫咪')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "CNN实现猫狗识别实战summary：\n",
    "1、通过搭建CNN模型，实现了对复杂图像的自动识别分类；\n",
    "2、掌握了图像数据的批量加载与图像增强方法；\n",
    "3、更熟练的掌握了keras的sequence结构，并嵌入卷积、池化层；\n",
    "4、实现了对网络图片的分类识别\n",
    "5、图像预处理参考资料：https://keras.io/preprocessing/image/"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "start_time": "2023-06-20T12:29:56.563511300Z"
    }
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
